/** @odoo-module **/

import { patch } from "@web/core/utils/patch";
import BarcodePickingModel from "@stock_barcode/models/barcode_picking_model";

/* —— 产品号逐字符比较：数字(0–9) < 字母(A–Z) < 其他；逐位；前缀短在前 —— */
function _rank(ch){ return ch>="0"&&ch<="9"?0: ch>="A"&&ch<="Z"?1:2; }
function _val(ch){ return ch>="0"&&ch<="9"?ch.charCodeAt(0)-48: ch>="A"&&ch<="Z"?ch.charCodeAt(0)-65: ch.charCodeAt(0); }
function _cmpBarcode(a,b){
  const A=(a||"").toString().trim().toUpperCase();
  const B=(b||"").toString().trim().toUpperCase();
  const n=Math.min(A.length,B.length);
  for(let i=0;i<n;i++){ const ra=_rank(A[i]), rb=_rank(B[i]); if(ra!==rb) return ra-rb;
    const va=_val(A[i]), vb=_val(B[i]); if(va!==vb) return va-vb; }
  return A.length-B.length;
}
function _lineCode(line){
  const p=(line&&line.product_id)||{};
  return p.barcode || line.product_barcode || p.default_code || p.display_name || "";
}

/* —— 取字段 —— */
function _seg(model, line){
  const done = Number(model.getQtyDone(line) || 0);
  if (done === 0) return 0;                    // 未扫描
  return line.result_package_id ? 2 : 1;       // 1=已扫未包, 2=已扫已包
}
function _locName(line){
  const loc = line && line.location_dest_id;
  if (!loc) return "";
  // 前端通常是 {id, display_name}；若有 name 则优先
  return (loc.name || loc.display_name || "") + "";
}
function _pkgKey(line){
  const p = line && line.result_package_id;
  if (!p) return ["", 0];                      // [name, id]
  if (typeof p === "object") return [(p.name||p.display_name||"")+"", Number(p.id||0)];
  if (Array.isArray(p)) return [(p[1]||"")+"", Number(p[0]||0)];
  return ["", Number(p) || 0];
}
function _timeStr(line){ return (line.x_last_scan_time || "") + ""; }

/* —— 时间降序：越晚越靠上；无时间排后 —— */
function _cmpTimeDesc(l1,l2){
  const s1=_timeStr(l1), s2=_timeStr(l2);
  if (s1 || s2){
    if (!s1 && s2) return 1;
    if (s1 && !s2) return -1;
    if (s1!==s2)   return s1 > s2 ? -1 : 1;   // 字典序与时间一致（YYYY-MM-DD HH:MM:SS）
  }
  return 0;
}

patch(BarcodePickingModel.prototype, {
  _sortingMethod(l1, l2) {
    // —— 先按段：0 未扫 → 1 已扫未包 → 2 已扫已包（升序）——
    const s1=_seg(this,l1), s2=_seg(this,l2);
    if (s1!==s2) return s1 - s2;

    if (s1 === 0) {
      // ① 未扫描：只按产品号
      const bc=_cmpBarcode(_lineCode(l1), _lineCode(l2));
      if (bc) return bc;
    } else if (s1 === 1) {
      // ② 已扫描未入包裹：时间降序 → 产品号
      const tc=_cmpTimeDesc(l1,l2); if (tc) return tc;
      const bc=_cmpBarcode(_lineCode(l1), _lineCode(l2)); if (bc) return bc;
    } else {
      // ③ 已扫描已入包裹：库位↑ → 包裹号↓ → 时间↓ → 产品号
      const ln1=_locName(l1), ln2=_locName(l2);
      if (ln1!==ln2) return ln1 < ln2 ? -1 : 1;

      const [pn1, pid1]=_pkgKey(l1), [pn2, pid2]=_pkgKey(l2);
      if (pn1 || pn2) {                        // 有名字时优先按名字降序
        if (pn1!==pn2) return pn1 > pn2 ? -1 : 1;
      } else if (pid1!==pid2) {                // 否则退回 id 降序
        return pid2 - pid1;
      }

      const tc=_cmpTimeDesc(l1,l2); if (tc) return tc;
      const bc=_cmpBarcode(_lineCode(l1), _lineCode(l2)); if (bc) return bc;
    }

    // —— 兜底：稳定排序 —— 
    const id1=l1.id||l1.virtual_id||0, id2=l2.id||l2.virtual_id||0;
    return id1 - id2;
  },
});
